﻿using NUnit.Framework;
using Sasa.QualityTools.CodeAnalysis.Core.Requests;
using Sasa.QualityTools.CodeAnalysis.Core.Services.CodeAnalysis;
using System;
using System.Collections.Generic;
using System.IO;

namespace Sasa.QualityTools.CodeAnalysis.Core.Tests.Unit.Services.CodeAnalysis
{
    [TestFixture]
    public class FxCopProjectAnalyzerTest
    {
        private static readonly string ResourceDirectory = Path.Combine("Resources", "Services", "CodeAnalysis", "FxCopProjectAnalyzer");

        private FxCopProjectAnalyzer testee;

        private FxCopProjectAnalysisRequest request;


        [SetUp]
        public void SetUp()
        {
            request = new FxCopProjectAnalysisRequest();
            request.FxCopCmdPath = Path.Combine(ResourceDirectory, "FxCopCmd.exe");
            request.FxCopProjectPath = Path.Combine(ResourceDirectory, "Project.FxCop");

            testee = new FxCopProjectAnalyzer(request);
        }

        [Test]
        [Description("FxCopReportValueConverter should return an instance of the FxCopReportValueConverter class.")]
        public void TestConverterType()
        {
            Assert.IsInstanceOf<FxCopReportValueConverter>(testee.FxCopReportValueConverter);
        }

        [Test]
        [Description("Output should return correct output path.")]
        public void TestOutputPath()
        {
            Assert.AreEqual(Path.Combine(ResourceDirectory, "CodeAnalysisReport.xml"), testee.OutputPath);
        }

        [Test]
        [Description("Output should throw an exception when an analysis target that is specified by Target of request doesn't exist.")]
        public void TestOutputPathWithInvalidRequest()
        {
            request.FxCopProjectPath = Path.Combine(ResourceDirectory, "NotExist.FxCop");
            Assert.Throws<InvalidOperationException>(() => { var path = testee.OutputPath; });
        }

        [Test]
        [Description("CreateFxCopCmdOptions should return correct FxCopCmd options.")]
        public void TestCreateFxCopCmdOptions()
        {
            var actual = testee.CreateFxCopCmdOptions();

            var expected = new string[] { "/p:" + '"' + request.FxCopProjectPath + '"', "/o:" + '"' + testee.OutputPath + '"' };
            CollectionAssert.AreEqual(expected, actual);
        }

        [Test]
        [Description("CreateFxCopCmdOptions should throw an exception when FxCop project that is specified by FxCopProjectPath of request doesn't exist.")]
        public void TestCreateFxCopCmdOptionsWithInvalidRequest()
        {
            request.FxCopProjectPath = Path.Combine(ResourceDirectory, "NotExist.FxCop");

            Assert.Throws<InvalidOperationException>(() => testee.CreateFxCopCmdOptions());
        }
    }
}
